package org.cybzacg.convert.enums;

import lombok.Getter;

/**
 * 转换优先级枚举 - 重新设计的9级层次化优先级体系
 * 按照类型层次定义转换器的优先级级别：
 * CRITICAL > ESSENTIAL > HIGH > MEDIUM_HIGH > MEDIUM > MEDIUM_LOW > LOW > FALLBACK > UNIVERSAL
 *
 * @author cybzacg.blog
 * @version 3.1
 * @since 3.1
 */
@Getter
public enum ConversionPriority {

    /**
     * 关键优先级 - 用于系统核心功能的关键转换器
     * 如null值处理、类型安全检查等
     */
    CRITICAL(1, "关键优先级", "系统核心功能转换器"),

    /**
     * 基础优先级 - 基本类型转换器
     * 如String、Boolean、Character等基本类型的转换
     */
    ESSENTIAL(2, "基础优先级", "基本类型转换器"),

    /**
     * 高优先级 - 数值类型转换器
     * 如Integer、Long、Double、BigDecimal等数值类型的转换
     */
    HIGH(3, "高优先级", "数值类型转换器"),

    /**
     * 中高优先级 - 日期时间转换器
     * 如Date、LocalDateTime、LocalDate等时间类型的转换
     */
    MEDIUM_HIGH(4, "中高优先级", "日期时间转换器"),

    /**
     * 中等优先级 - 集合转换器
     * 如List、Set、Map等集合类型的转换
     */
    MEDIUM(5, "中等优先级", "集合转换器"),

    /**
     * 中低优先级 - 数组转换器
     * 各类型数组的转换
     */
    MEDIUM_LOW(6, "中低优先级", "数组转换器"),

    /**
     * 低优先级 - 对象转换器
     * 如Entity、DTO等复杂对象的转换
     */
    LOW(7, "低优先级", "对象转换器"),

    /**
     * 兜底优先级 - 自定义转换器
     * 用户自定义的转换器，作为特定场景的兜底方案
     */
    FALLBACK(8, "兜底优先级", "自定义转换器"),

    /**
     * 通用优先级 - 通用转换器
     * 如UniversalTypeConverter，作为最后的兜底选择
     */
    UNIVERSAL(9, "通用优先级", "通用转换器");

    private final int level;
    private final String name;
    private final String description;

    ConversionPriority(int level, String name, String description) {
        this.level = level;
        this.name = name;
        this.description = description;
    }

    /**
     * 获取优先级数值（用于排序）
     * 数值越小优先级越高
     *
     * @return 优先级数值
     */
    public int getValue() {
        return level * 10;
    }

    /**
     * 根据级别获取优先级
     *
     * @param level 级别
     * @return 优先级
     */
    public static ConversionPriority fromLevel(int level) {
        for (ConversionPriority priority : values()) {
            if (priority.getLevel() == level) {
                return priority;
            }
        }
        return UNIVERSAL;
    }

    /**
     * 根据数值获取优先级
     *
     * @param value 优先级数值
     * @return 优先级
     */
    public static ConversionPriority fromValue(int value) {
        int level = value / 10;
        return fromLevel(level);
    }

    /**
     * 检查是否为关键优先级
     *
     * @return 是否为关键优先级
     */
    public boolean isCritical() {
        return this == CRITICAL;
    }

    /**
     * 检查是否为基础优先级
     *
     * @return 是否为基础优先级
     */
    public boolean isEssential() {
        return this == ESSENTIAL;
    }

    /**
     * 检查是否为高优先级
     *
     * @return 是否为高优先级
     */
    public boolean isHigh() {
        return this == HIGH;
    }

    /**
     * 检查是否为中高优先级
     *
     * @return 是否为中高优先级
     */
    public boolean isMediumHigh() {
        return this == MEDIUM_HIGH;
    }

    /**
     * 检查是否为中等优先级
     *
     * @return 是否为中等优先级
     */
    public boolean isMedium() {
        return this == MEDIUM;
    }

    /**
     * 检查是否为中低优先级
     *
     * @return 是否为中低优先级
     */
    public boolean isMediumLow() {
        return this == MEDIUM_LOW;
    }

    /**
     * 检查是否为低优先级
     *
     * @return 是否为低优先级
     */
    public boolean isLow() {
        return this == LOW;
    }

    /**
     * 检查是否为兜底优先级
     *
     * @return 是否为兜底优先级
     */
    public boolean isFallback() {
        return this == FALLBACK;
    }

    /**
     * 检查是否为通用优先级
     *
     * @return 是否为通用优先级
     */
    public boolean isUniversal() {
        return this == UNIVERSAL;
    }

    /**
     * 检查是否为系统级优先级（CRITICAL和ESSENTIAL）
     *
     * @return 是否为系统级优先级
     */
    public boolean isSystemLevel() {
        return this == CRITICAL || this == ESSENTIAL;
    }

    /**
     * 检查是否为用户级优先级（FALLBACK和UNIVERSAL）
     *
     * @return 是否为用户级优先级
     */
    public boolean isUserLevel() {
        return this == FALLBACK || this == UNIVERSAL;
    }

    /**
     * 获取优先级分组
     *
     * @return 优先级分组
     */
    public PriorityGroup getGroup() {
        if (level <= 2) return PriorityGroup.SYSTEM;
        if (level <= 4) return PriorityGroup.HIGH;
        if (level <= 6) return PriorityGroup.MEDIUM;
        return PriorityGroup.LOW;
    }

    /**
     * 比较优先级
     *
     * @param other 其他优先级
     * @return 如果当前优先级更高返回负数，相等返回0，更低返回正数
     */
    public int comparePriority(ConversionPriority other) {
        return Integer.compare(this.getValue(), other.getValue());
    }

    /**
     * 检查当前优先级是否高于指定优先级
     *
     * @param other 其他优先级
     * @return 是否更高
     */
    public boolean isHigherThan(ConversionPriority other) {
        return this.level < other.level;
    }

    /**
     * 检查当前优先级是否低于指定优先级
     *
     * @param other 其他优先级
     * @return 是否更低
     */
    public boolean isLowerThan(ConversionPriority other) {
        return this.level > other.level;
    }

    @Override
    public String toString() {
        return String.format("Level %d (%s) - %s: %d", level, name, description, getValue());
    }

    /**
     * 优先级分组枚举
     */
    public enum PriorityGroup {
        SYSTEM("系统级", 1, 2),
        HIGH("高级", 3, 4),
        MEDIUM("中级", 5, 6),
        LOW("低级", 7, 9);

        private final String name;
        private final int minLevel;
        private final int maxLevel;

        PriorityGroup(String name, int minLevel, int maxLevel) {
            this.name = name;
            this.minLevel = minLevel;
            this.maxLevel = maxLevel;
        }

        public String getName() {
            return name;
        }

        public int getMinLevel() {
            return minLevel;
        }

        public int getMaxLevel() {
            return maxLevel;
        }

        public boolean contains(int level) {
            return level >= minLevel && level <= maxLevel;
        }
    }
}
